package bancosys.tec.rtm;

import java.util.HashMap;
import java.util.Map;

/**
 * Classe auxiliar do RTM para adicionar mais informações ao erro. Deve ser inicializado com {@link #initialize()} tipicamente em um filtro
 * web, interceptadores EJB, ou mecanismos parecido e, ao final do processamento, deve ser finalizado com {@link #cleanup()}. As informacoes
 * são compartilhadas apenas para um thread
 * 
 * @author takeshi
 */
public final class ExceptionContext {

    private static final ThreadLocal<ExceptionContext> CONTEXT = new ThreadLocal<ExceptionContext>();

    private Map<String, String> entries = new HashMap<String, String>();

    /**
     * C'tor privado
     */
    private ExceptionContext() {
    }

    /**
     * Devolve o contexto atual se foi inicializado ou um contexto vazio caso contrario. O contexto vazio não é guardado.
     * 
     * @return {@link ExceptionContext}
     */
    public static ExceptionContext getCurrentContext() {
        ExceptionContext exceptionContext = CONTEXT.get();
        if (exceptionContext == null) {
            return new ExceptionContext();
        }
        return exceptionContext;
    }

    /**
     * @return boolean
     */
    public static boolean hasContext() {
        return CONTEXT.get() != null;
    }

    /**
     * Inicializa o contexto para a thread atual
     */
    public static void initialize() {
        if (CONTEXT.get() != null) {
            throw new IllegalStateException("Already initialized!");
        }
        CONTEXT.set(new ExceptionContext());
    }

    /**
     * Finaliza o contexto da thread atual
     */
    public static void cleanup() {
        if (CONTEXT.get() == null) {
            throw new IllegalStateException("Not initialized!");
        }
        CONTEXT.remove();
    }

    /**
     * @param key String
     * @param value String
     */
    public void put(String key, String value) {
        this.entries.put(key, value);
    }

    /**
     * @return the entries
     */
    public Map<String, String> getEntries() {
        return new HashMap<String, String>(entries);
    }

    /**
     * Apaga todas as entradas
     */
    public void clear() {
        entries = new HashMap<String, String>();
    }

}
